﻿/******************************************************************************
* File description: PurifyCanvas.qml
* Function: 纯化动画绘制
* Current Version: 1.0.0
* Author: JNN
* Date: 2025-07-01
*  -----
*  Copyright by 博坤生物 .
 *****************************************************************************/


import QtQuick 2.0
import "../../components"
import CObjectAnimation 1.0

Rectangle {
    id: root
    property int valveNum: 15
    property color bcgColor: Qt.rgba(224/255, 230/255, 233/255, 1)

    color: bcgColor

    radius: 5*dp

    property int controller: 0  // 0:设备 1:实验模拟
//    property int gCollectContainer: gCollectContainer  // 0:显示转盘  1:显示蠕动泵

    property bool showDetails: false        // 是否显示阀门按钮
    property real liquidFlowArrowIdx: 1

    // 预设 ==========================================================================================
    property real cScale: 1.36    // 画布的宽高比

    property int syringeNum: 7
    property var sSyringeStandardH: 0.2
    property var sSyringeStandardW: 0.05

    property var sSyringeH: []
    property var sSyringeW: []

    property var lenBase: Math.min(canvas.width, canvas.height*cScale)


    property var labelW: 0.028
    property var labelH: 0.023
    property var _pPumpState: 0

    property var pipeWidth: lenBase*0.005


    // 绘制信息 =======================================================================================

    // 注射器
    property var syringeColor: ["lightcoral", "gold", "darksalmon", "lightgreen", "mediumpurple", "deepskyblue", "orange"] // 注射器颜色
    property var syringeName: ["溶靶瓶", "溶靶液", "PH调节液", "溶靶混匀瓶", "盐酸", "纯水", "草酸"]
    property var syringePercentage: [0.2, 0.4, 0.9, 0, 1, 0.2, 0.4]                         // 注射器液体量
    property var syringeIsPushing: [0, 0, 0, 0, 0, 0, 0, 0]     // 注射器是否在推
    property var syringeSpeed1: [1, 1, 1, 1, 1, 1, 1]
    property var syringeSpeed2: [1, 1, 1, 1, 1, 1, 1]

    // 色谱柱粒子特效
    property var particlePosiY: [1.2, 1.2, 1.2, 1.2, 1.2, 1.2]
    property var particlePosiX: [0.14, 0.28, 0.4, 0.57, 0.68, 0.86]
    property var particleSize: [0.12, 0.1, 0.05, 0.06, 0.1, 0.12]

    // 检测器
    property bool detectorGlowVisible: false
    property real detectorGlowAngle: 0

    // 转盘
    property real wheelAngle: 0
    property real wheelPosiNum: 9

    // 瓶帽
    property int hatNum: 10
    property real pressPosi: 0
    property real pushPosi: 0

    // 阀门角度 (0.5代表开 0代表关)
    property var valveAngle: [0, 0.5, 0, 0.5, 0, 0, 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0] // 下标从0开始算


    // 瓶子
    property var bottleHat: [false, true, false, true, false, true, false, false, false]

    // 加热
    property bool heatingState: false

    // 管道 (路径中液体流动的长度)
//    property var liquidStates: [
//        { path: [12, 0, 3, 13, 19],
//          pathStart: 0.11,
//          pathEnd: 0.22,
//          pathColor: Qt.rgba(255/255, 133/255, 166/255, 0.5)}  // length以width为基准
//    ]

//    property var liquidStates: [
//        {
//            v1: 1,
//            v2: 2,
//            segment: []
//        }
//    ]

    property var liquidStates: [
        [
            1,      // v1
            2,      // v2
            0.1,    // seg1_length
            1       // seg1_color
        ]
    ]
    property var liquidFlowState: [0, 1, 0]

    property int dissolveTime: 300

    property real pi: Math.PI


    function startAnimation(){
        timer.start()
    }
    function stopAnimation(){
        timer.stop()
    }

    // 绘制处理 =======================================================================================
    Timer{
        id: timer
        interval: 30
        repeat: true
        onTriggered: {
            if(root.visible){
                updateState()
            }
        }
    }

    PurifyCanvasMouseArea{
        visible: showDetails
        anchors.fill: parent
        z: 12
    }

    PurifyCanvasPosition{
        id: pfPosi
    }

    function copyValue_object(res){

        syringePercentage   = res.syringePercentage
        syringeIsPushing    = res.syringeIsPushing
        sSyringeH           = res.syringeHeight
        sSyringeW           = res.syringeWidth
        hatNum              = res.hatNum
        pressPosi           = res.pressPosi
        pushPosi            = res.pushPosi
        valveAngle          = res.valveAngle
//        liquidStates      = res.pathList
        liquidStates        = res.liquidState
        bottleHat           = res.bottleHasHat
        syringeColor        = res.syringeColor
        syringeSpeed1       = res.syringeSpeed1
        syringeSpeed2       = res.syringeSpeed2
        particlePosiY       = res.particlePosi
        detectorGlowVisible = res.detectorGlowVisible
        detectorGlowAngle   = res.detectorGlowAngle
//        gCollectContainer = res.gCollectContainer
        _pPumpState         = res.pPumpState
        heatingState        = res.heatingState
        liquidFlowState    = res.liquidFlowState;

//        console.log(syringeIsPushing)
//        console.log(liquidFlowState)

        setWheelPosi(res.wheelPosi)
    }

    function copyValue(res){

        syringePercentage = res["SyringePercentage"]
        syringeIsPushing = res["SyringeIsPushing"]
        sSyringeH = res["SyringeHeight"]
        sSyringeW = res["SyringeWidth"]
        setWheelPosi(res["WheelPosi"])
        hatNum = res["HatNum"]
        pressPosi = res["PressPosi"]
        pushPosi = res["PushPosi"]
        valveAngle = res["ValveAngle"]
//        liquidStates = res["PathList"]
        liquidStates = res["LiquidState"]
        bottleHat = res["BottleHasHat"]
        syringeColor = res["SyringeColor"]
        syringeSpeed1 = res["SyringeSpeed1"]
        syringeSpeed2 = res["SyringeSpeed2"]
        particlePosiY = res["ParticlePosi"]
        detectorGlowVisible = res["DetectorGlowVisible"]
        detectorGlowAngle = res["DetectorGlowAngle"]
//        gCollectContainer = res["gCollectContainer"]
        _pPumpState = res["PPumpState"]
        heatingState = res["HeatingState"]

    }

//    function updateStateFrame(frame){
//        let res = CAnimationPurify.requestInfo_frame(frame, controller)
//        copyValue(res)
//        refresh()
//    }

    function updateState(){

//        console.time("TimeRequestInfo")
        let res = CAnimationPurify.requestInfo_object()
        copyValue_object(res)
//        console.timeEnd("TimeRequestInfo")

//        console.time("TimeRefresh")
        refresh()
//        console.timeEnd("TimeRefresh")
    }

    function refresh(){
        canvas.requestPaint()
    }

    function setWheelPosi(posi){
        let bias = 0.35*pi       // 修正值
        wheelAngle = pi*2* posi/wheelPosiNum + bias
    }

    function drawHolePlate(ctx, x1, y1, x2, y2){
        ctx.drawImage("qrc:/picture/base.png", x1, y1, x2-x1, y2-y1)
    }

    function drawSyringe(ctx, x, y, w, h, color, percent, drawPushRod, text, idx, hbias){

        percent = Math.min(percent, 1)
        percent = Math.max(percent, 0)

        // 底下那个东西的高度
        let bottomHeight = height*0.06
        let bottomWidth = height*0.06
        // 推杆比注射器高的高度
        let bias_T_C = h*0.12
        // 活塞的高度（注射器不能推满的那一段
        let bias_CC = h*0.18
        // 注射器的高度
        let centerHeight = h - bias_T_C
        let centerWidth = w
        // 推杆的高度
        let topHeight = h
        let topWidth = w

        // aq的最上端和最下端
        let aqBottom = y - bottomHeight
        let aqTop = aqBottom - (centerHeight - bias_CC)*percent
        ctx.fillStyle = color
        ctx.fillRect(x-0.6*centerWidth/2, aqTop, 0.6*centerWidth, aqBottom-aqTop)

        // 注射器的推杆
        if(drawPushRod){
            ctx.drawImage("qrc:/picture/syringe_top.png",x-topWidth/2, aqTop-topHeight-4*dp, topWidth, h)
        }

        // 注射器的管子
        ctx.drawImage("qrc:/picture/syringe_center_15.png", x-centerWidth/2, aqBottom-centerHeight, centerWidth, centerHeight+4*dp)

        // 注射器管子上的箭头 (第0个注射器不用画)
        if(idx !== 0){
            if(syringeIsPushing[idx] === 1){            // 向下推时的箭头
                ctx.drawImage("qrc:/picture/animation/liquidArrow/down_" + Math.floor(liquidFlowArrowIdx) + ".png", x-centerWidth*0.25, aqBottom-centerHeight*0.7, centerWidth*0.5, centerHeight*0.5+4*dp);
            }else if(syringeIsPushing[idx] === -1){     // 向上推时的箭头
                ctx.drawImage("qrc:/picture/animation/liquidArrow/up_" + Math.floor(liquidFlowArrowIdx) + ".png", x-centerWidth*0.25, aqBottom-centerHeight*0.7, centerWidth*0.5, centerHeight*0.5+4*dp);
            }
        }

        // 注射器的底座
        ctx.drawImage("qrc:/picture/syringe_bottom.png", x-bottomWidth/2, y-bottomHeight+2*dp, bottomWidth, bottomHeight-2*dp)


        if(idx === 0 && heatingState){
            ctx.drawImage("qrc:/picture/syringe_heating.png", x-centerWidth/2, aqBottom-centerHeight, centerWidth, centerHeight+4*dp)
        }

        let fontsize = sSyringeStandardW*lenBase*0.24
        ctx.font = fontsize.toString() + "px Verdana"

        ctx.fillStyle = "#FFF"
        // 瓶盖上的序号
//        if(idx !== 0)
//            ctx.fillText(idx.toString(), x-fontsize*0.33, y-fontsize*0.15)

        ctx.fillStyle = "#555555"
//        // 瓶身上的字
//        for(let i = 0; i < text.length; i ++){
//            ctx.fillText(text[i], x-fontsize/2 + (/^[a-zA-Z]*$/.test(text[i])?fontsize*0.2:0), y-h/2+(i*fontsize)-text.length*fontsize/2, w)
//        }


    }

    function drawWheel(ctx, x0, y0, rx, ry, h, curAngle, posiNum){


        let gapAngle = 2*pi / posiNum       // 瓶子之间的角度间隔
        let rrx = rx*0.7, rry = ry*0.7

        // 瓶盖尺寸
        let bottleTopW = 0.3*rx
        let bottleTopH = 1.2*bottleTopW
        // 瓶身尺寸
        let bottleBotW = 0.3*rx
        let bottleBotH = 0.3*ry

        // 计算每个瓶子的中心 (绝对坐标)
        var bCenterX = []
        var bCenterY = []
        for(let i = 0; i < posiNum; i ++){
            let bottleAngle = (2*pi - gapAngle*i + curAngle) > 2*pi ? (2*pi - gapAngle*i + curAngle) - 2*pi : (2*pi - gapAngle*i + curAngle)
            let bottleX = rrx * Math.cos(bottleAngle)
            let bottleY = rrx * Math.sin(bottleAngle) * (ry/rx)
            bCenterX.push(x0+bottleX)
            bCenterY.push(y0-bottleY)
        }
        // 画瓶身
        for(let i = 0; i < posiNum; i ++){
            ctx.drawImage("qrc:/picture/bottle_bottom.png", bCenterX[i]-bottleBotW/2, bCenterY[i], bottleBotW, bottleBotH)
        }
        // 上面的椭圆
        ctx.drawImage("qrc:/picture/circle.png", x0-rx, y0-ry, 2*rx, 2*ry)

        // 瓶盖
        for(let i = 0; i < posiNum; i ++){
            ctx.drawImage("qrc:/picture/bottle_top.png", bCenterX[i]-bottleTopW/2, bCenterY[i]-bottleTopH*0.9, bottleTopW, bottleTopH)
            let fontsize = Math.min(Math.floor(labelH*lenBase*0.75), 24)
            ctx.font = fontsize.toString() + "px serif"
            ctx.fillStyle = "#666666"
            ctx.fillText((i+1).toString(), bCenterX[i]-5, bCenterY[i])
        }
        for(let i = 0; i < posiNum; i ++){
            if(bottleHat[i]){
                ctx.drawImage("qrc:/picture/bottle_top_hat.png", bCenterX[i]-bottleTopW/2, bCenterY[i]-bottleTopH*0.9, bottleTopW, bottleTopH)
            }
        }

        ctx.drawImage("qrc:/picture/circleBase.png", x0-rx, y0, 2*rx, 2*ry-4)

    }

    function drawValve(ctx, x, y, raw_angle, rotate_state, idx){
        let size = lenBase*0.02
        ctx.save()
        ctx.translate(x, y)
        ctx.rotate(Math.PI*(raw_angle+rotate_state+0.5))
        ctx.translate(-x, -y)
        ctx.drawImage(rotate_state===0?"qrc:/picture/valve_off.png":"qrc:/picture/valve_on.png", x-size*0.5, y-size*0.5, size, size)
        ctx.restore()

//        // 阀门旁边标注(中心坐标)
//        let labelX = x + pfPosi.valveLabel[idx].x*lenBase * labelW
//        let labelY = y + pfPosi.valveLabel[idx].y*lenBase * labelH
//        ctx.fillStyle = Qt.rgba(135/255, 149/255, 177/255, 0.9)
//        let fontsize = Math.min(Math.floor(labelH*lenBase*0.63), 20)
//        ctx.fillRect(labelX-labelW*canvas.width/2, labelY-labelH*lenBase/2, Math.min(labelW*canvas.width, fontsize*3.2), Math.min(labelH*lenBase, fontsize*1.8))        // 我也不知道这一堆尺寸是怎么算的了……
//        ctx.fillStyle = "black"
//        ctx.font = fontsize.toString() + "px serif"
//        ctx.fillText((idx>9?"":" ")+"阀"+idx.toString(), labelX-fontsize, labelY+fontsize*0.35)


    }

    function drawBar(ctx, x, y, width, height){     // 放瓶盖的那个棍(传入左下角的坐标)
        ctx.drawImage("qrc:/picture/bcg_bar.png", x, y-height, width, height)
    }function drawBar2(ctx, x, y, width, height){     // 放瓶盖的那个棍
        ctx.drawImage("qrc:/picture/bcg_bar_top.png", x, y-height, width, height)
        ctx.fillStyle = "white"
        ctx.fillText(hatNum.toString(), x+width*0.55, y-height*0.75)
    }
    function drawPress(ctx, x, y, width, height){
        ctx.drawImage("qrc:/picture/bcg_press.png", x, y, width, height)
    }
    function drawPush1(ctx, x, y, width, height){
        ctx.drawImage("qrc:/picture/bcg_push.png", x, y, width, height)
    }
    function drawPush2(ctx, x, y, width, height){
        ctx.drawImage("qrc:/picture/bcg_push2.png", x, y, width, height)
    }
    function drawTrashBin1(ctx, x, y, width, height){   // 传入x中心坐标和y坐标顶部
        ctx.drawImage("qrc:/picture/trashBin1.png", x-width/2, y, width, height)
    }
    function drawTrashBin2(ctx, x, y, width, height){   // 传入x中心坐标和y坐标顶部
        ctx.drawImage("qrc:/picture/trashBin2.png", x-width/2, y, width, height)
    }
    function drawTrasnBinDouble(ctx, x1, y1, x2, y2){
        ctx.drawImage("qrc:/picture/trashBin_double.png", x1 - (x2-x1)*0.4, y1, (x2-x1)*1.8, (x2-x1)*2.2)
    }
    function drawColumn(ctx, x, y, width, height){      // 传入xy为中心坐标
        ctx.drawImage("qrc:/picture/column.png", x-width/2, y-height/2, width, height)
        ctx.fillStyle = "yellow"


        x = x-width*0.28
        y = y-height*0.11
        width = width*0.56
        height = height*0.26
        for(let i = 0; i < particlePosiY.length; i ++){
            if(particlePosiY[i] < 0 || particlePosiY[i] > 1){
                continue
            }
            ctx.beginPath()
            ctx.arc(x+particlePosiX[i]*width, y+height-(particlePosiY[i]*height), particleSize[i]*width, 0, Math.PI*2)
            ctx.fill()
        }
    }function drawDetector(ctx, x, y, width, height){       // 中心坐标
        ctx.drawImage("qrc:/picture/detector.png", Math.round(x-width/2), Math.round(y-height/2), Math.round(width), Math.round(height))
        ctx.strokeStyle = "#555555"
        ctx.lineWidth = Math.min(height, width)*0.02
        ctx.beginPath()
        ctx.arc(x, y, Math.min(height, width)/2, 0, 2*Math.PI)
        ctx.stroke()

        if(detectorGlowVisible){

            ctx.lineCap = "butt"
            ctx.strokeStyle = "#00FFFF"

            ctx.lineWidth = Math.min(height, width)*0.02
            ctx.beginPath()
            ctx.arc(x, y, Math.min(height, width)*1.25/2, 0, 2*Math.PI)
            ctx.stroke()

            ctx.lineWidth = Math.min(height, width)*0.11
            ctx.beginPath()
            ctx.arc(x, y, Math.min(height, width)*1.25/2, detectorGlowAngle, detectorGlowAngle+1.5*Math.PI)
            ctx.stroke()
        }
    }
    function drawHat(ctx, x, y, width, height){ // 传入x中心和y底部 尺寸为单个帽的尺寸
        for(let i = 0; i < 10; i ++){
            ctx.drawImage("qrc:/picture/hat.png", x-width/2, y-(i+1)*(height+1), width, height)
        }
    }

    function drawPipe(ctx){
        ctx.lineWidth = root.pipeWidth
        ctx.lineCap = "round"
        ctx.strokeStyle = "white"
        for(let i = 0; i < pfPosi.vertexNum; i ++){
            for(let j = 0; j < i; j ++){
                if(CAnimationPurify.isVertexConnect(i, j)){

                    if(gCollectContainer === 0){              // 转盘模式不画管子26-28
                        if(pfPosi.vertex[i].idx === 26 || pfPosi.vertex[i].idx === 27 || pfPosi.vertex[i].idx === 28){
                            continue
                        }
                    }

                    ctx.beginPath()

                    let x1 = pfPosi.vertex[i].x*canvas.width
                    let y1 = pfPosi.vertex[i].y*canvas.height
                    let x2 = pfPosi.vertex[j].x*canvas.width
                    let y2 = pfPosi.vertex[j].y*canvas.height

                    ctx.moveTo(x1, y1)
                    ctx.lineTo(x2, y2)
                    ctx.stroke()
                }
            }
        }
    }
    function drawSupplementalPipe(ctx){
        ctx.lineWidth = root.pipeWidth
        ctx.strokeStyle = "orange"
        for(let i = 0; i < pfPosi.supVertex.length; i ++){
            ctx.beginPath()
            ctx.moveTo(pfPosi.supVertex[i].x1*canvas.width, pfPosi.supVertex[i].y1*canvas.height)
            ctx.lineTo(pfPosi.supVertex[i].x2*canvas.width, pfPosi.supVertex[i].y2*canvas.height)
            ctx.stroke()
        }
    }

    function drawLiquidPath(ctx, path, length, color){

//        let curLength = 0
//        let totalLength = length * canvas.width
//        ctx.beginPath()
//        ctx.lineWidth = root.pipeWidth
//        ctx.strokeStyle = color
//        ctx.moveTo(pfPosi.vertex[path[0]].x*canvas.width, pfPosi.vertex[path[0]].y*canvas.height)
//        for(let v = 0; v < path.length-1; v ++){
//            let l = pfPosi.calDistance(path[v], path[v+1], canvas.width, canvas.height)
//            if(l+curLength < totalLength){
//                ctx.lineTo(pfPosi.vertex[path[v+1]].x*canvas.width, pfPosi.vertex[path[v+1]].y*canvas.height)
//                curLength += l
//            }else{
//                let percentage = (totalLength-curLength) / l
//                let x1 = pfPosi.vertex[path[v]].x*canvas.width      // 开始点
//                let y1 = pfPosi.vertex[path[v]].y*canvas.height
//                let x2 = pfPosi.vertex[path[v+1]].x*canvas.width    // 结束点
//                let y2 = pfPosi.vertex[path[v+1]].y*canvas.height
//                ctx.lineTo(x1 + percentage*(x2-x1), y1 + percentage*(y2-y1))
//                break
//            }
//        }
//        ctx.stroke()
    }

    function drawLiquid(ctx){
//        V1.0已弃用
//        for(let i = 0; i < liquidStates.length; i ++){
//            drawLiquidPath(ctx, liquidStates[i].path, liquidStates[i].pathEnd, liquidStates[i].pathColor)
//            drawLiquidPath(ctx, liquidStates[i].path, liquidStates[i].pathStart, "white")
//        }
        ctx.lineWidth = root.pipeWidth

        for(let i = 0; i < liquidStates.length; i ++){
            let line = liquidStates[i]
            let v1 = line[0]
            let v2 = line[1]
            let startPercent = 0;

            if(gCollectContainer === 0){              // 转盘模式不画管子26-28
                if(v1 === 26 || v1 === 27 || v1 === 28){
                    continue
                }
            }

            for(let s = 2; s < line.length; s += 2){

                if(line[s+1] === 9 || (line[s+1]-Math.floor(line[s+1])===0.5)){
                    ctx.strokeStyle = "white"
                }else{
                    ctx.strokeStyle = syringeColor[line[s+1]]
                }
                ctx.beginPath()
                ctx.moveTo( pfPosi.vertex[v1].x*canvas.width + startPercent*(pfPosi.vertex[v2].x-pfPosi.vertex[v1].x)*canvas.width,
                           pfPosi.vertex[v1].y*canvas.height + startPercent*(pfPosi.vertex[v2].y-pfPosi.vertex[v1].y)*canvas.height )
                startPercent += line[s]
                ctx.lineTo( pfPosi.vertex[v1].x*canvas.width + startPercent*(pfPosi.vertex[v2].x-pfPosi.vertex[v1].x)*canvas.width,
                           pfPosi.vertex[v1].y*canvas.height + startPercent*(pfPosi.vertex[v2].y-pfPosi.vertex[v1].y)*canvas.height )
                ctx.stroke()



                //        let curLength = 0
                //        let totalLength = length * canvas.width
                //        ctx.beginPath()
                //        ctx.strokeStyle = color
                //        ctx.moveTo(pfPosi.vertex[path[0]].x*canvas.width, pfPosi.vertex[path[0]].y*canvas.height)
                //        for(let v = 0; v < path.length-1; v ++){
                //            let l = pfPosi.calDistance(path[v], path[v+1], canvas.width, canvas.height)
                //            if(l+curLength < totalLength){
                //                ctx.lineTo(pfPosi.vertex[path[v+1]].x*canvas.width, pfPosi.vertex[path[v+1]].y*canvas.height)
                //                curLength += l
                //            }else{
                //                let percentage = (totalLength-curLength) / l
                //                let x1 = pfPosi.vertex[path[v]].x*canvas.width      // 开始点
                //                let y1 = pfPosi.vertex[path[v]].y*canvas.height
                //                let x2 = pfPosi.vertex[path[v+1]].x*canvas.width    // 结束点
                //                let y2 = pfPosi.vertex[path[v+1]].y*canvas.height
                //                ctx.lineTo(x1 + percentage*(x2-x1), y1 + percentage*(y2-y1))
                //                break
                //            }
                //        }
                //        ctx.stroke()
            }
        }


    }

    function drawLiquidFlowState(ctx){
        for(let i = 0; i < liquidFlowState.length; i += 3){
            // 只对管子0->3 13->19 21->10画液路效果
//            if(liquidFlowState[i] === 0 && liquidFlowState[i+1]===3){     // ……算了，0->3不画了，还是斜着的……
//            }
            if(liquidFlowState[i] === 13 && liquidFlowState[i+1]===19 && liquidFlowState[i+2] !== 0){    // 13->19
                ctx.drawImage("qrc:/picture/animation/liquidArrow/" + Math.floor(liquidFlowArrowIdx) + ".png",
                              (pfPosi.vertex[13].x+pfPosi.vertex[19].x)*width*0.5 - 0.04*width,
                              pfPosi.vertex[13].y*height-pipeWidth*0.6,
                              0.08*width,
                              pipeWidth * 1.2
                              )
            }if(liquidFlowState[i] === 10 && liquidFlowState[i+1]===21 && liquidFlowState[i+2] !== 0){
                ctx.drawImage("qrc:/picture/animation/liquidArrow/down_"  + Math.floor(liquidFlowArrowIdx)  + ".png",
                              pfPosi.vertex[21].x*width - 0.6*pipeWidth,
                              (pfPosi.vertex[21].y+pfPosi.vertex[10].y)*0.5*height - 0.05*height,
                              pipeWidth * 1.2,
                              0.1*height
                              )
            }
        }
    }

    // 传入转盘的位置
    function drawWheelAssembly(ctx, x1, y1, x2, y2){
        let width = x2-x1
        let height = y2-y1
        drawBar(ctx, x2-width*0.4,     y2-0.06*width, width*0.8, width*1.5)      // 放螺丝的杆
        drawHat(ctx, x2+width*0.074,    y2-0.45*width, 0.08*width, 0.05*width)
        drawBar2(ctx, x2-width*0.4,    y2-0.06*width, width*0.8, width*1.5)      // 放螺丝的杆(再罩上)
        drawPress(ctx, x1+width*0.56,    y1-height*0.4*(2.8-pressPosi),      width*0.49, width*0.2)

        drawPush1(ctx, x2+0.13*width,                    y1-1*height,  width*0.32,   width*0.2)
        drawPush2(ctx, x2+0.13*width-pushPosi*width*0.3, y1-1*height,  width*0.32,   width*0.2)
        drawWheel(ctx, (x1+x2)*0.5, (y1+y2)*0.5, width*0.5, height*0.5, 100, wheelAngle, wheelPosiNum)
    }

    // 绘制蠕动泵
    function drawPeristalticPump(ctx, x, y){
        let w = pfPosi.pPump.width * width
        let h = 0.18*height
        ctx.drawImage("qrc:/picture/animation/peristalticPump.png", x, y, w, h)
    }
    // 绘制溶靶罐
    function drawCollectPot(ctx, x, y){
        let w = 0.03*height
        let h = 0.15*height
        ctx.drawImage("qrc:/picture/animation/collectPot.png", x-w/2, y, w, h)
    }


    Canvas{
        id: canvas
        anchors.centerIn: parent
//        height: Math.min(root.height, root.width/cScale)
//        width: Math.min(root.height*cScale, root.width)
        x: 0*dp; y: 20*dp
        width: parent.width
        height: parent.height
        onPaint: {
            var ctx = canvas.getContext("2d")
            // 清空画布
            ctx.fillStyle = root.bcgColor
            ctx.fillRect(0, 0, width, height)

            drawHolePlate(ctx, pfPosi.base.x1*width, pfPosi.base.y1*height, pfPosi.base.x2*width, pfPosi.base.y2*height)

            // 管道
            drawPipe(ctx);
            drawSupplementalPipe(ctx);
            drawLiquid(ctx)
            drawLiquidFlowState(ctx)

            // 注射器
            for(let i = syringeNum-1; i >= 0; i --){
                drawSyringe(ctx, pfPosi.syringe[i].x*width, pfPosi.syringe[i].y*height,
                            sSyringeW[i]*lenBase, sSyringeH[i]*lenBase,
                            syringeColor[i], syringePercentage[i],
                            i!==0, syringeName[i], i,
                            (0.2-sSyringeH[i])*lenBase*0.16)
            }

            // 阀门
            for(let i = 1; i < pfPosi.valve.length; i ++){
                drawValve(ctx, pfPosi.valve[i].x*width, pfPosi.valve[i].y*height, pfPosi.valve[i].angle, valveAngle[i-1], i)
            }

//            drawTrashBin1(ctx, width*pfPosi.trashBin1.x, height*pfPosi.trashBin1.y, lenBase*0.03, lenBase*0.14)
//            drawTrashBin2(ctx, width*pfPosi.trashBin2.x, height*pfPosi.trashBin2.y, lenBase*0.03, lenBase*0.14)
            drawTrasnBinDouble(ctx, width*pfPosi.trashBin1.x, height*pfPosi.trashBin1.y, width*pfPosi.trashBin2.x, height*pfPosi.trashBin2.y)
            drawColumn(ctx, pfPosi.column.x*width, pfPosi.column.y*height, lenBase*0.022, lenBase*0.15)
            drawDetector(ctx, pfPosi.detector.x*width, pfPosi.detector.y*height, lenBase*0.08, lenBase*0.08)

            if(gCollectContainer === 0){
                drawWheelAssembly(ctx, width*0.658, height*0.83, width*0.7+width*0.14, height*0.83+width*0.065)
            }else if(gCollectContainer === 1){
                drawCollectPot(ctx, pfPosi.collectPot1.x*width, pfPosi.collectPot1.y*height)
                drawCollectPot(ctx, pfPosi.collectPot2.x*width, pfPosi.collectPot2.y*height)
                drawPeristalticPump(ctx, pfPosi.pPump.x*width, pfPosi.pPump.y*height)
            }

            liquidFlowArrowIdx += 0.1
            if(liquidFlowArrowIdx >= 6){
                liquidFlowArrowIdx -= 5
            }

        }
    }
    property int speedType: 1       // 0-mm/s 1-ml/min
    Item{           // 一些文字标注在qml里面做了
        anchors.fill: canvas
        opacity: 0.85
        visible: root.showDetails

        // 针头上面的速率
        Repeater{
            model: syringeNum-1
            Rectangle{
                property bool isHovered: false
                color: syringeIsPushing[index+1]!==0 ? Qt.rgba(196/255, 188/255, 101/255, 1) : Qt.rgba(135/255, 149/255, 177/255, 1)
                radius: 5
                x: pfPosi.syringe[index+1].x*canvas.width-width/2;
//                y: 0.09*canvas.height - 0.9*width
                height: 0.9*width;  width: Math.min(parent.width * 0.05, parent.height * 0.14)

                Rectangle{
                    height: 0.32*parent.height; width: 0.92*parent.width
                    x: 0.04*parent.width; y: 0.04*parent.height
                    radius: 3
                    color: Qt.rgba(224/255, 230/255, 233/255)
                    Text{
                        anchors.centerIn: parent
                        text: syringeSpeed1[index+1].toFixed(2)
                        font.pixelSize: config.fontsize-1*dp
                    }
                }Rectangle{
                    height: 0.32*parent.height; width: 0.92*parent.width
                    x: 0.04*parent.width; y: 0.4*parent.height
                    radius: 3
                    color: Qt.rgba(224/255, 230/255, 233/255)
                    Text{
                        anchors.centerIn: parent
                        text: syringeSpeed2[index+1].toFixed(2)
                        font.pixelSize: config.fontsize-1*dp
                    }
                }Item{
                    height: 0.28*parent.height; width: 0.92*parent.width
                    x: 0.04*parent.width; y: 0.72*parent.height
                    Text{
                        id: text_unit
                        anchors.centerIn: parent
                        text: speedType===0 ? "mm/s" : "mL/Min"
                        font.pixelSize: config.fontsize - 1*dp
                    }
                }
                MouseArea{
                    anchors.fill: parent
                    hoverEnabled: true
                    cursorShape: Qt.PointingHandCursor
                    onEntered: { parent.isHovered = true }
                    onExited: { parent.isHovered = false }
                    onClicked: {
                        speedType = 1-speedType
                        CAnimationPurify.changeSpeedUnit(speedType)
                    }
                }
                CustomTooltip{
                    visible: parent.isHovered
                    text: "点击切换速度单位"
                }
            }
        }

        // 时间
        Rectangle{
            color: Qt.rgba(171/255, 181/255, 199/255)
            radius: 5
            y: canvas.height * 0.28;  x: pfPosi.vertex[0].x*canvas.width - width/2
            height: canvas.height*0.08; width: text_timeTitle.contentWidth + 10*dp
            Text{
                id: text_timeTitle
                color: "#333333"
                text: "溶靶时间"
                font.pixelSize: config.fontsize + 3*dp
                anchors.centerIn: parent
                anchors.verticalCenterOffset: -10*dp
            }
            Text{
                id: text_time
                color: "white"
                text: dissolveTime/60 + "分" + (dissolveTime%60>9?"":"0") + dissolveTime%60 + "秒"
                font.bold: true
                anchors.centerIn: parent
                font.pixelSize: config.fontsize + 3*dp
                anchors.verticalCenterOffset: 10*dp
            }
        }
    }
    CustomAnimatedImage{
        id: gif_running_left
        source: "qrc:/picture/animation/rotate_right.gif"
        playing: visible
        visible: _pPumpState === -1
        height: 0.04*parent.height; width: 0.03*parent.width
        y: pfPosi.pPump.y*parent.height + pfPosi.pPump.height*parent.height*0.2
        x: pfPosi.pPump.x*parent.width + pfPosi.pPump.width*parent.width*0.28
    }
    CustomAnimatedImage{
        id: gif_running_right
        source: "qrc:/picture/animation/rotate_left.gif"
        playing: visible
        visible: _pPumpState === 1
        height: 0.04*parent.height; width: 0.03*parent.width
        y: pfPosi.pPump.y*parent.height + pfPosi.pPump.height*parent.height*0.2
        x: pfPosi.pPump.x*parent.width + pfPosi.pPump.width*parent.width*0.28
    }

    Repeater{

        model: 6
        Text{
            text: index+1
            color: "white"
            font.pixelSize: config.fontsize
            x: pfPosi.syringe[index+1].x * root.width - 0.25*font.pixelSize
            y: pfPosi.syringe[index+1].y * root.height - 1.35*font.pixelSize
        }
    }

}
